package com.xcity.game.assist;

import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.xcity.db.entity.Employee;
import com.xcity.db.entity.Player;
import com.xcity.game.buildv2.BuildV2;
import com.xcity.game.employee.EmployeeListener;
import com.xcity.game.io.SerializeStream;
import com.xcity.game.io.Serializer;
import com.xcity.game.io.SerializerUtils;
import com.xcity.game.player.cache.PlayerCacheService;

import naga.x.App;
import naga.x.common.Updatable;
import naga.x.game.time.TimeUpdater;

public class AssistManager implements Updatable, Serializer, EmployeeListener{

	protected Player owner;
	protected List<AssistBuild> assistBuildList;
	@Deprecated
	protected List<AssistInvite> assistInviteList;
	protected long nextUpdateTime;
	
	public static final int ASSIST_UPDATE_CD = 10 * 60 * 1000;
	
	public AssistManager(Player player, List<AssistBuild> builds) {
		this.owner = player;
		this.assistBuildList = builds != null? builds : new ArrayList<AssistBuild>();
		this.assistInviteList = null;//invites != null?  invites : new ArrayList<AssistInvite>();
	}

	/**
	 * 协助者
	 */
	public Player getOwner(){
		return owner;
	}
	
	public void setOwner(Player player){
		this.owner = player;
	}
	
	public List<AssistBuild> getAssistBuildList() {
		return assistBuildList;
	}

	public List<AssistInvite> getAssistInviteList() {
		return assistInviteList;
	}
	
	public AssistBuild findByOwnerId(long ownerId){
		for(int i = 0, size = assistBuildList.size(); i < size; i++){
			AssistBuild assbuild = assistBuildList.get(i);
			if(assbuild.getOwnerId() == ownerId){
				return assbuild;
			}
		}
		return null;
	}
	
	@Deprecated
	/**
	 * 增加一个新的邀请
	 * 返回新的invite
	 * @return
	 */
	public AssistInvite tryAddNewInvite(long owner, int buildid){
		AssistInvite invite = null;
		for(int i = 0, size = assistInviteList.size(); i < size; i++){
			AssistInvite oldInvite = assistInviteList.get(i);
			if(oldInvite.owner == owner){
				invite = oldInvite;
				break;
			}
		}
		if(invite != null){
			return null;
		}
		invite = new AssistInvite(this.owner.getId(), owner, buildid);
		assistInviteList.add(invite);
		return invite;
	}
	
	/**
	 * 接受邀请并移除邀请 成功返回true
	 */
	public boolean tryRemoveInvite(long owner, int buildid){
		for(int i = assistInviteList.size() - 1; i > -1; i--){
			AssistInvite oldInvite = assistInviteList.get(i);
			if(oldInvite.owner == owner && oldInvite.buildId == buildid){
				assistInviteList.remove(i);
				return true;
			}
		}
		return false;
	}
	
	public AssistBuild tryAddNewAssistBuild(long owner, int buildid, long[] eids, long now){
		for(int i = assistBuildList.size() - 1; i > -1; i--){
			if(assistBuildList.get(i).ownerId == owner){
				assistBuildList.remove(i);
			}
		}
		AssistBuild assistBuild = new AssistBuild(this, owner, buildid, eids, now);
		assistBuildList.add(assistBuild);
		return assistBuild;
	}
	
	public synchronized AssistBuild tryRemoveAssistBuild(long ownerId, int buildid){
		for(int i = assistBuildList.size() - 1; i > -1; i--){
			AssistBuild assbuild = assistBuildList.get(i);
			if(assbuild.ownerId == ownerId && assbuild.id == buildid){
				return assistBuildList.remove(i);
			}
		}
		return null;
	}
	
	@Override
	public String toString(){
		return JSON.toJSONString(assistBuildList);//+ ";" + JSON.toJSONString(assistInviteList);
	}

	@Override
	public boolean update() {
		long now  = TimeUpdater.getInstance().now();
		if(now > nextUpdateTime){
			nextUpdateTime = now + ASSIST_UPDATE_CD;
			updateBuildList(now);
		}
		return true;
	}
	
	private void updateBuildList(long now){
		if(assistBuildList.size() == 0){
			return;
		}
		PlayerCacheService pcs = App.getApp().getServiceManager().get(PlayerCacheService.class);
		for(int i = assistBuildList.size() - 1; i > -1; i--){
			AssistBuild assbuild = assistBuildList.get(i);
			if(now < assbuild.assistStartTime + BuildV2.BUILD_RETURN_MILLISECOND){
				continue;
			}
			Player owner = pcs.find(assbuild.ownerId);
			if(owner != null){
				BuildV2 b = owner.getBuildings2().find(assbuild.id);
				if(b != null){
					if(b.getAssistId() == this.getOwner().getId() && b.getAssistId() > 0){
						assistBuildList.remove(i);
						assbuild.takeMoney(this.getOwner(), now, b, true);
//						int[] ret = assbuild.calcMoney(now, b.getTemplate().getProduceMoneyFactor());
//						if(ret[0] > 0){
//							MailAttach attach = new MailAttach(ret[0], 0);
//							String title = MessageConst.ASSIST_BUILD_TAKE_MONEY;
//							String content = MessageFormat.format(MessageConst.ASSIST_BUILD_TAKE_MONEY_CONTENT, b.getTemplate().getName(), ret[0]);
//							App.getApp().getServiceManager().get(MailService.class).sendSystemMail(owner.getId(), title, content, attach);
//						}
//						if(ret[1] > 0){
//							MailAttach attach = new MailAttach(ret[1], 0);
//							String title = MessageConst.ASSIST_BUILD_TAKE_MONEY_ASS;
//							String content = MessageFormat.format(MessageConst.ASSIST_BUILD_TAKE_MONEY_CONTENT_ASS, owner.getName(), ret[1]);
//							App.getApp().getServiceManager().get(MailService.class).sendSystemMail(this.getOwner().getId(), title, content, attach);
//						}
						b.reset();
					}
				}
			}
		}
	}
	
	@Override
	public void fireEmployeeRemoved(Employee e){
		long now = TimeUpdater.getInstance().now();
		final PlayerCacheService pcs = App.getApp().getServiceManager().get(PlayerCacheService.class);
		for(int i = 0; i < assistBuildList.size(); i++){
			AssistBuild assbuild = assistBuildList.get(i);
			if(assbuild != null && assbuild.employees != null){
				for(int j = 0, len = assbuild.employees.length; j < len; j++){
					if(assbuild.employees[j] == e.getId()){
						Player owner = pcs.find(assbuild.ownerId);
						if(owner != null){
							BuildV2 b = owner.getBuildings2().find(assbuild.id);
							if(b != null){
								if(b.getAssistId() == this.getOwner().getId() && b.getAssistId() > 0){
									assistBuildList.remove(i);
									assbuild.takeMoney(this.getOwner(), now, b, true);
									b.reset();
								}
							}
						}
						break;
					}
				}
			}
		}
	}

	@Override
	public void write(SerializeStream out) {
		SerializerUtils.serialize(this, out);
	}
}
